Link to this headingApplication Components

  • Activity: Point of user interaction with the application, most commonly through a UI screen or window
  • Broadcast Receiver: Listens for and receives messages from
    applications and the Android system
  • Content Provider: Application data storage (SQLite databases)
  • Service: Operates in the background to provide long-running
    application functionality without user interaction

Parameters: Look for putExtra(key, value), get*Extra(key) or getData() to see what parameters are taken from a Android Intent. Look for getQueryParameter for parameters names.

Link to this headingActivities

These Activities must be declared in the Manifest file. These are the UI views that can be shown to the user. The start funciton of the app is a Activity that can be called by any application. This is how a homescreen opens the app when the icon is pressed.

Activity Lifecycle:

  • onCreate(): When the Activity Starts this function is called.

  • onStart(): When the Activity Starts this function is called after onCreate(). This is run when the activity is shown to the user.

  • onResume(): This is called when the Activity is foregrounded after onStart(). This is also called when the app is running but switches from another Activity.

  • onPause(): This is run when the Application starts another activity, switches to another application, when receiving a phone call, or the device screen’s turning off.

  • onStop(): This occurs when the a new activity covers the entire screen or when the activity has finished running.

  • onDestroy(): This occurs after the onStop callback.

android:exported

  • If set to true this Activity be launched by another application.
  • If this has an intent-filter in it then it is exported by default
  • If set to false can only be launched by components of the same application or the same user ID. This is the default value.
  • Look for getString

Link to this headingSecurity

Get Activity information from a Application:

dz> run app.activity.info --package com.cisco.webex.meetings Package: com.cisco.webex.meetings com.cisco.webex.meetings.ui.premeeting.welcome.WebExMeeting Permission: null com.cisco.webex.meetings.ui.integration.AssistantActivity Permission: null com.cisco.webex.meetings.ui.integration.DeepLinkActivity Permission: null com.cisco.webex.meetings.ui.integration.IntegrationActivity Permission: null com.cisco.webex.meetings.ui.integration.IntegrationInternalActivity Permission: com.cisco.webex.permission.INTERNAL_BROADCAST com.cisco.webex.meetings.ui.integration.IntegrationWrapAccountActivity Permission: null com.cisco.webex.meetings.ui.premeeting.ShortcutActivity Permission: null com.microsoft.identity.client.BrowserTabActivity Permission: null com.smartdevicelink.transport.USBAccessoryAttachmentActivity Permission: null

Launch an Activity with Drozer:

dz> run app.activity.start --component com.cisco.webex.meetings com.cisco.webex.meetings.ui.premeeting.welcome.WebExMeeting dz> run app.activity.start --component com.cisco.webex.meetings com.cisco.webex.meetings.ui.integration.AssistantActivity dz> run app.activity.start --component com.example.app.client com.example.app.client.ui.SettingsActivity --extra string Uri "file:///sdcard/Download/nm_settings.json"

Start an Activity from the commandline:

am start -n com.example.app.client/.ui.SettingsActivity -a android.intent.action.VIEW -d file:///sdcard/Download/nm_settings.json am start -n com.example.app.client/.ui.ImportUserCertificateActivity -a android.intent.action.VIEW -d file:///sdcard/Download/crt.p12 --eu Password test --ez Standalone True adb shell am start -n com.quora.android/com.quora.android.ModalContentActivity -e url 'http://test/test' -e html '<script>alert(QuoraAndroid.getClipboardData());</script>'

Finding an Activity in Code:

  • startActivity()
  • getExtras()

Link to this headingLaunch Activity PoC

public Class MainAcitivity extends AppCampatActivity { public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstatnceState); setContentView(R.layout.activity_main); } /** Called when the user taps the Send button */ public void sendMessage(View view){ Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.editText); String message = editText.getText().toString; intent.putExtra(EXTRA_MESSAGE, message); startActivity(intent); } }

Link to this headingFragments

These are partial UI views similar to Activities but don’t need to be declared in the Manifest File.

FLAG_SECURE: On an fragment prevents information from being shown on the application switcher.

Link to this headingBroadcast/Intent Receiver

  • Enable applications to receive messages/triggers that are broadcast by the system or by other applications,
    • This can happen when the application is not running.
    • Example getting a text message, incoming call, or a notification
  • Can be created in the Manifest file or by Code.
  • This information is not secret since it can be listened to by other applications on the device

android:exported

  • If set to true this Receiver can receive intents from other applications. This is the default value if their are intent filters.
  • If set to false can only be launched by components of the same application or the same user ID. This is the default value if their are no intent filters.

Link to this headingSecurity

List Broadcast Receiver in a Application:

dz> run app.broadcast.info --package com.cisco.webex.meetings Package: com.cisco.webex.meetings com.cisco.webex.meetings.receiver.MeetingStatusUpdater Permission: com.cisco.webex.permission.INTERNAL_BROADCAST com.cisco.webex.meetings.receiver.LocaleChangeReceiver Permission: com.cisco.webex.permission.UI_BROADCAST com.cisco.webex.meetings.receiver.SendLogStatusReceiver Permission: com.cisco.webex.permission.UI_BROADCAST com.cisco.webex.meetings.receiver.MeetingWidgetProvider Permission: com.cisco.webex.permission.INTERNAL_BROADCAST com.cisco.webex.meetings.SdlReceiver Permission: null com.cisco.webex.meetings.receiver.AppIndexingUpdateReceiver Permission: com.google.android.gms.permission.APPINDEXING com.cisco.webex.meetings.receiver.CreateShortcutReceiver Permission: com.cisco.webex.permission.UI_BROADCAST com.cisco.webex.meetings.receiver.MeetingAutoEndReceiver Permission: com.cisco.webex.permission.UI_BROADCAST com.google.firebase.iid.FirebaseInstanceIdReceiver Permission: com.google.android.c2dm.permission.SEND com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver Permission: android.permission.INSTALL_PACKAGES

Sending a Broadcast from the commandline:

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test from adb"

Sending a Broadcast from Drozer:

dz> run app.broadcast.send --action (broadcast receiver name) --extra (number of arguments)

Link to this headingCode Review

  • Check AndroidManifest for <intent-filter> this limits what the service is subscribed to.
  • Check the onReceive function to see what is pulled from the context and the Intent.

Checking in Code:

  • BroadcastReceiver
  • onReceive
  • IntentFilter
  • .addAction
  • registerReciever

Link to this headingServices

  • Must be declared in the Manifest file.
  • Is a background task that can be run when not in the foreground.
  • Is started using Intents

Viewing Android Services:

>>> adb shell service list Found 138 services: 0 nfc: [android.nfc.INfcAdapter] 1 cneservice: [com.quicinc.cne.ICNEManager] 2 ims: [com.android.ims.internal.IImsService] 3 timezone: [android.app.timezone.IRulesManager] 4 otadexopt: [android.content.pm.IOtaDexopt] 5 android.service.gatekeeper.IGateKeeperService: [] 6 AtCmdFwd: [com.qualcomm.atfwd.IAtCmdFwd] 7 sip: [android.net.sip.ISipService] [...]

android:exported

  • If set to true this Activity be launched by another application. This is the default value if their are intent filters.
  • If set to false can only be launched by components of the same application or the same user ID. This is the default value if their are no intent filters.

android:permission

  • specifies if the caller needs a specific permission to launch the service. By default the service is not protected by a permission.

Link to this headingSecurity

List all services from an application:

dz> run app.service.info --package com.cisco.webex.meetings Package: com.cisco.webex.meetings com.cisco.webex.meetings.SdlRouterService Permission: null com.cisco.webex.meetings.service.AccountAuthenticatorService Permission: com.cisco.webex.permission.INTERNAL_BROADCAST com.cisco.webex.meetings.service.AccountSyncAdapterService Permission: com.cisco.webex.permission.INTERNAL_BROADCAST com.cisco.webex.meetings.service.WBXUrlApiService Permission: null com.cisco.webex.meetings.service.WBXInfoService Permission: null com.cisco.webex.meetings.service.WBXService Permission: null com.cisco.webex.meetings.service.WBXUrlApiSecureService Permission: com.cisco.webex.permission.UI_BROADCAST com.cisco.webex.watch.adapter.PhoneWearableService Permission: null com.cisco.webex.notification.WbxFirebaseMessagingService Permission: null

Start a Service from Commandline:

adb shell am startservice android.nfc.INfcAdapter

Start a Service from Drozer:

Link to this headingStart Service PoC

Intent intent = new Intent(this, HelloService.class); startService(intent);

Link to this headingContent Providers

  • Usually connected to a database

Can be viewed from content://com.example.app.provider/table1/1 or content://com.example.app.provider/table2/*

Read from the Provider:

>>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ >>> content query --uri content://settings/secure --projection name:value --where "name=\'new_setting\'" --sort "name ASC" >>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort "_id" >>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort '_id/**/limit/**/\(select/**/1/**/from/**/sqlite_master/**/where/**/1=1\)' >>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort '_id/**/limit/**/\(select/**/1/**/from/**/sqlite_master/**/where/**/1=2\)'

Write to the Provider:

>>> content insert --uri content://settings/secure --bind name:s:new_setting --bind value:s:new_value >>> content update --uri content://settings/secure --bind value:s:newer_value --where "name='new_setting'" >>> content delete --uri content://settings/secure --where "name='new_setting'"

Check to see if there is a Permission to Read and Write the Provider. If not then any application can read and write these values.

Link to this headingSecurity

Detect SQL injections in content providers:

dz> run scanner.provider.injection -a (package name) dz> run scanner.provider.traversal -a com.mwr.example.sieve

Checking in Code:

  • Grep for ContentProvider
  • Grep for onReceive

Link to this headingFile Provider

A file provider allows other application to access specific files and folders.

To view a file from this Provider try content://com.example.myapp.fileprovider/myimages/default_image.jpg